#encoding:utf-8
'''
Created on 6 avr. 2011

@author: paraita

    Gigue: question 1.7.3
    
    On voit bien qu'avec un Td d'une seconde coté client,
    le serveur ne les recoit pas au même tempo de son côté
    le Td n'est pas garanti d'être le même !
    
    pour tester le talkie walkie il faut lancer le script sur
    2 machines différentes
    si une des machines est un mac, il faudra lancer la fonction spécifique
    
    l'utilisation se fait comme avec skype, on peut parler en meme temps que
    l'autre; le programme est multiforké et relié grace a des pipes la ou il faut
    
    
'''

#import alsaaudio
import sys
import os
import time
import random
import socket
from matplotlib import pylab
from Bruit import soundeffects

def serveur_gigue(p=8080):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind(("",p))
    sortie = False
    trace = []
    start_flag = time.time()
    cnt = 1
    while not sortie:
        datagrm, addr = s.recvfrom(8)
        if datagrm:
            end_flag = time.time()
            trace.append(end_flag-start_flag)
            start_flag = end_flag
            print str(cnt) + " ",
            cnt += 1
        if not datagrm.find("fini") == -1 :
            sortie = True
    s.close()
    return trace

def client_gigue(addr="127.0.0.1",p=8080,limite=10,td=1):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    i = 0
    while i < limite:
        s.sendto(str(int(random.random()*100000000)), (addr, p))
        time.sleep(1)
        i += 1
    s.sendto("fini", (addr, p))
    s.close()

def gigue():
    PORT=8082
    LIMITE=20
    TRACE = []
    
    print "patientez " + str(LIMITE) + " secondes..."
    
    pid = os.fork()
    
    if pid:
        TRACE = serveur_gigue(p=PORT)
        os.waitpid(pid, os.WNOHANG)
    else:
        client_gigue("127.0.0.1", PORT, LIMITE,1)
        sys.exit()
        
    #pylab.plot(range(LIMITE),TRACE)
    #pylab.show()
    pylab.hist(TRACE,range(LIMITE))
    pylab.show()

def capture_micro(fd=0):
    inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL)
    inp.setchannels(1)
    inp.setrate(8000)
    inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)
    inp.setperiodsize(512)
    while True:
        l,data = inp.read()
        if l:
            os.write(fd, data)
            
def to_speaker(fd=0):
    out = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, alsaaudio.PCM_NORMAL)
    out.setchannels(1)
    out.setrate(8000)
    out.setformat(alsaaudio.PCM_FORMAT_S16_LE)
    out.setperiodsize(512)
    data = os.read(fd, 512*2)
    while True:
        if not data == "":
            out.write(data)
        data = os.read(fd, 512*2)

def capture_reseau(fd=0,port=8080):
    sockin = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sockin.bind(("", port))
    while True:
        datagrm, addr = sockin.recvfrom(512*2)
        if datagrm:
            print datagrm
            os.write(fd, datagrm)

def envoi_reseau(fd=0,ip_dest=0,port_dest=8080):
    sockout = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    while True:
        data = os.read(fd, 512*2)
        if data:
            sockout.sendto(data, (ip_dest, port_dest))

def talkiewalkie_linux():
    PORT=9006
    pid = os.fork()
    
    if pid:
        rd,wd = os.pipe()
        ppid = os.fork()
        if ppid:
            os.close(wd)
            #IP = raw_input()
            IP = "192.168.0.16"
            envoi_reseau(fd=rd, ip_dest=IP, port_dest=PORT)
        else:
            os.close(rd)
            capture_micro(fd=wd)
    else:
        rd,wd = os.pipe()
        ppid = os.fork()
        if ppid:
            os.close(rd)
            capture_reseau(fd=wd,port=PORT+1)
        else:
            os.close(wd)
            to_speaker(fd=rd)

'''
def talkiewalkie_osx():
    PORT=9100
    pid = os.fork()
    
    if pid:
        rd,wd = os.pipe()
        ppid = os.fork()
        if ppid:
            os.close(wd)
            #IP = raw_input()
            IP = "192.168.0.16"
            envoi_reseau(fd=rd, ip_dest=IP, port_dest=PORT)
        else:
            os.close(rd)
            soundeffects.capture_micro_osx(fd=wd)
    else:
        rd,wd = os.pipe()
        ppid = os.fork()
        if ppid:
            os.close(rd)
            capture_reseau(fd=wd,port=PORT+1)
        else:
            os.close(wd)
            soundeffects.to_speaker_osx(fd=rd)
'''         

if __name__ == '__main__':
    talkiewalkie_linux()
    
    
    
    
    
    
    